package com.huawei.spare.part.replace;

/*
 * #%L
 * igniter
 * %%
 * Copyright (C) 2013 - 2016 Adam Bien
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

import com.airhacks.afterburner.injection.Injector;
import com.huawei.spare.part.replace.framework.SmartDataBus;
import com.huawei.spare.part.replace.framework.SmartRouter;
import com.huawei.spare.part.replace.views.dashboard.DashboardView;
import com.huawei.spare.part.replace.views.widgets.Alerts;
import com.jfoenix.controls.JFXDecorator;
import java.util.Optional;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import uk.org.lidalia.sysoutslf4j.context.LogLevel;
import uk.org.lidalia.sysoutslf4j.context.SysOutOverSLF4J;

/**
 * @author adam-bien.com
 */
public class App extends Application {

  static final Logger logger = LoggerFactory.getLogger(App.class);

  private static DashboardView dashboard;

  @Override
  public void start(Stage stage) throws Exception {
    logger.info("Start application now");
    Font.loadFont(getClass().getResourceAsStream("/font/PingFang-SC-Regular.otf"), 10);
    //        Font.loadFont(getClass().getResourceAsStream("/font/PingFang-SC-Semibold.otf"), 10);
    //        Font.loadFont(getClass().getResourceAsStream("/font/PingFang-SC-Medium.otf"), 10);
    stage.setTitle(SmartDataBus.get().getBundle().getString("app.title"));
    stage.setScene(getDecoratorDashboardScene(stage));
    stage.setResizable(false);
    stage.show();

    SmartDataBus.get().setDashboard(dashboard);
    SmartDataBus.get().setStage(stage);
    Platform.runLater(() -> {
      logger.info("Redirect system out/error to slf4j");
      SysOutOverSLF4J.sendSystemOutAndErrToSLF4J(LogLevel.DEBUG, LogLevel.WARN);

      // setup close event handler
      EventHandler<WindowEvent> confirmCloseEventHandler = event -> {
        Alert confirm = new Alert(
            Alert.AlertType.CONFIRMATION,
            Alerts.i18n("app.exit.confirm")
        );
        Button exitButton = (Button) confirm.getDialogPane().lookupButton(
            ButtonType.OK
        );
        exitButton.setText(Alerts.i18n("button.exit"));
        confirm.setHeaderText(Alerts.i18n("app.exit.title"));
        confirm.initOwner(stage);

        Optional<ButtonType> closeResponse = confirm.showAndWait();
        if (!ButtonType.OK.equals(closeResponse.get())) {
          event.consume();
        } else {
          SmartRouter.get().onViewStackCleared();
        }
      };
      stage.setOnCloseRequest(confirmCloseEventHandler);
    });

    logger.info("Application started");
  }

  private Scene getDecoratorDashboardScene(Stage stage) {
    dashboard = new DashboardView();
    JFXDecorator decorator = new JFXDecorator(stage, dashboard.getView(), false, false, true);
    Scene scene = new Scene(decorator);
    String decoratorCssPath = "views/assets/css/jfx-decorator.css";
    String decoratorCssAbsPath = getClass().getResource(decoratorCssPath).toExternalForm();
    scene.getStylesheets().add(decoratorCssAbsPath);
    return scene;
  }

  @Deprecated
  private Scene getDashboardScene(Stage stage) {
    dashboard = new DashboardView();
    Scene scene = new Scene(dashboard.getView(), Constants.StagePrefWidth, Constants.StagePrefHeight);
    return scene;
  }

  @Override
  public void stop() throws Exception {
    Injector.forgetAll();
  }

  public static void main(String[] args) {
    Thread.setDefaultUncaughtExceptionHandler((t, e) -> {
      if (e instanceof OperationException) {
        final OperationException convert = (OperationException) e;
        Alerts.error(convert.getMajor(), convert.getDetails());
      } else {
        logger.warn("uncaught exception in thread: " + t.getName(), e);
        Alerts.error(e);
      }
    });
    launch(args);
  }
}
